// ShaderManager.cpp

#include "stdafx.h"
#include "RenderSystem.h"
#include "ShaderManager.h"

ShaderManager::ShaderManager(RenderSystem *render_system, const String& shader_directory) 
: m_render_system(render_system)
, m_allocator(128)
, m_directory(shader_directory)
{

};

ShaderManager::~ShaderManager() {
	if(m_shaders.empty()) {return;};
	ShaderMap::iterator it=m_shaders.begin();
	while(it!=m_shaders.end()) {
		it->second->Release();
		++it;
	};
	m_shaders.clear();
};

Shader *ShaderManager::Create(const String &vertex_shader,const String &pixel_shader) {
	ShaderMap::iterator it=m_shaders.find(std::make_pair(m_directory + vertex_shader,m_directory + pixel_shader));
	if(it==m_shaders.end()) {
		Shader *shader=m_allocator.Allocate();
		if(!m_render_system->CreateShader(shader,m_directory + vertex_shader,m_directory + pixel_shader)) {
			m_allocator.Free(shader);
			return nullptr;
		};
		m_shaders.insert(std::make_pair(std::make_pair(m_directory + vertex_shader,m_directory + pixel_shader),shader));
		it=m_shaders.find(std::make_pair(m_directory + vertex_shader,m_directory + pixel_shader));

		m_render_system->CreateShader(it->second, m_directory + vertex_shader, m_directory + pixel_shader);

		//int vs_s[]={sizeof(OncePerFrame), sizeof(OncePerObject)};
		//int ps_s[]={sizeof(DirectionalLight)};
		//it->second->AllocateVSConstants(2,vs_s);
		//it->second->AllocatePSConstants(1,ps_s);
		//m_render_system->CreateConstantBuffers(it->second);

		//Sampler sampler;
		//m_render_system->CreateSamplerState(&sampler,AM_WRAP,AM_WRAP,AM_WRAP,FM_LINEAR,CM_NEVER);
		//it->second->AllocateSamplers(1);
		//it->second->SetSampler(0,sampler);

		//D3D10_INPUT_ELEMENT_DESC desc[]={
		//	{"POSITION",0,DXGI_FORMAT_R32G32B32_FLOAT,0,0,D3D10_INPUT_PER_VERTEX_DATA,0},
		//	{"TEXCOORD",0,DXGI_FORMAT_R32G32_FLOAT,0,12,D3D10_INPUT_PER_VERTEX_DATA,0},
		//	{"NORMAL",0,DXGI_FORMAT_R32G32B32_FLOAT,0,20,D3D10_INPUT_PER_VERTEX_DATA,0}
		//};

		//m_render_system->CreateInputLayout(it->second,desc,3);
	};

	return it->second;
};

void ShaderManager::Destroy(Shader *shader) {
	ShaderMap::iterator it=m_shaders.begin();
	while(it!=m_shaders.end()) {
		if(it->second==shader) {
			shader->Release();
			m_shaders.erase(it);
			break;
		};
		++it;
	};
};
